package finalgame.Engine;

import finalgame.Game;
import finalgame.Engine.moves.Move;
import finalgame.Engine.pokemon.Pokemon;
import finalgame.Engine.trainer.Trainer;
import finalgame.Engine.trainer.trainerAI;

public class Battle {
	private Trainer player, opponent;
	private Pokemon playerPokemon, opposingPokemon;
	public static final int I_LOST = 1;
	public static final int ENEMY_LOST = 2;
	public static final int NORMAL = 0;
	private boolean opponentCaught;
	
	public Battle(Trainer trainerP, Trainer trainerO){
		player = trainerP;
		opponent = trainerO;
		playerPokemon = player.getCurrentPokemon();
		opposingPokemon = opponent.getCurrentPokemon();
	}
	public Battle(Trainer trainerP, Pokemon oppPokemon){
		player = trainerP;
		playerPokemon = trainerP.getCurrentPokemon();
		opposingPokemon = oppPokemon;
	}
	
	public Trainer getMe() {
		return player;
	}
	
	public Pokemon getMyPokemon() {
		return playerPokemon;
	}
	
	public Trainer getOpponent() {
		return opponent;
	}
	
	public Pokemon getOpponentPokemon() {
		return opposingPokemon;
	}
	//Attacker parameter is 0 if attacker is the player's pokemon, 1 if attacker is opponent's pokemon
	//Returns null if opponent faints before using ability, "Opposer's name + 'has used'" if opponent used move successfully
	public String performAction(String ability){
		String battleHistory = "";
		Move action;
		
		if(checkState() == ENEMY_LOST) return "This battle is done.";
		
		if(ability == null) {
			action = null;
		} else if(ability.equalsIgnoreCase("catch")) {
			action = null;
			battleHistory += catchPokemon();
			if(opponentCaught) return battleHistory;
			battleHistory += "\n";
		} else if(ability.equalsIgnoreCase("flee")){
			if(canFlee()) return "Got away safely.";
			action = null;
			battleHistory += "Can't escape!\n";
		} else {
			action = Move.getNewMove(ability);
		}
		Move oppaction = trainerAI.selectMove(opposingPokemon, playerPokemon);
		
		if(opposingPokemon.getHP() <= 0) {
			return null;
		}
		
		if(playerPokemon.getHP() <= 0)
			return "Alert, you must switch pokemon";
		
		if(playerPokemon.getSpeed() >= opposingPokemon.getSpeed()) {
			if(action != null){
				action.use(playerPokemon, opposingPokemon);
				battleHistory += playerPokemon.getName() + " has used " + action.getClass().getSimpleName().substring(4) + "!\n"; 
			}
			if(opposingPokemon.getHP() <= 0){
				battleHistory += opposingPokemon.getName() + " fainted!" + switchPokemon();
			} else {
				if(!Game.god) {
					oppaction.use(opposingPokemon, playerPokemon);
					battleHistory += opposingPokemon.getName() + " has used " + oppaction.getClass().getSimpleName().substring(4) + "!";
				} else
					battleHistory += opposingPokemon.getName() + " is quaking in fear of your epicness!";
			}
		}
		else {
			if(!Game.god) {
				oppaction.use(opposingPokemon, playerPokemon);
				battleHistory += opposingPokemon.getName() + " has used " + oppaction.getClass().getSimpleName().substring(4) + "!\n";
			} else
				battleHistory += opposingPokemon.getName() + " is quaking in fear of your epicness!\n";
			//Prevents player's pokemon ability usage if fainted by last move
			if(playerPokemon.getHP() <= 0){
				battleHistory += playerPokemon.getName() + " fainted!"; 
			}
			else if(action != null){
				action.use(playerPokemon, opposingPokemon);
				battleHistory += playerPokemon.getName() + " has used " + action.getClass().getSimpleName().substring(4) + "!";
				if(opposingPokemon.getHP() <= 0){
					battleHistory += "\n" + opposingPokemon.getName() + " fainted!" + switchPokemon();
				}
			}
		}
		return battleHistory;
	}
	
	private String switchPokemon() {
		String ret = "";
		if(opponent != null) {
			Pokemon p = trainerAI.selectPokemon(opponent, playerPokemon);
			if(p == null) return "";
			opposingPokemon = p;
			ret =  "\n" + opponent.getName() + " sent out " + p.getName() + ".";
		}
		playerPokemon.addExp(opposingPokemon.expGiven());
		playerPokemon.LevelUp();
		return ret;
	}
	
	public String catchPokemon() {
		if(opponent != null){
			return "You can't catch trainer-owned Pokemon!";
		}
		if(Catch.catchPokemon(opposingPokemon)){
			opponentCaught = true;
			player.addPokemon(opposingPokemon);
			return opposingPokemon.getName() + " has been caught!";
		}
		return opposingPokemon.getName() + " broke free!";
	}
	
	
	
	//Returns 1 if player pokemon fainted, 2 if opponent pokemon fainted, 0 if no pokemon fainted
	public int checkState() {
		if(player.isBeaten()){
			return I_LOST;
		}
		else if(opponent == null) {
			if(opposingPokemon.getHP() <= 0 || opponentCaught) {
				return ENEMY_LOST;
			}
		}
		else if(opponent.isBeaten()) {
			return ENEMY_LOST;
		}
		return NORMAL;
	}
	
	//Returns 2 if oponent is trainer, 1 if enemy wild pokemon is faster, and 0 if can flee
	public boolean canFlee(){
		if(opponent != null){
			if(opposingPokemon.getHP() > 0)
				return false;
			return true;
		}
		else if(opposingPokemon.getSpeed() >= playerPokemon.getSpeed() && !opponentCaught){
			return false;
		}
		else{
			return true;
		}
	}
	
	public void switchPlayerPokemon(int newIndex) {
		player.switchPokemon(newIndex);
		playerPokemon = player.getCurrentPokemon();
	}
	
	public void switchAIPokemon(int newIndex) {
		opponent.switchPokemon(newIndex);
		opposingPokemon = opponent.getCurrentPokemon();
	}
}
